package com.horizon.balance;

import com.horizon.constants.ServerConstants;
import com.horizon.entity.ImNode;
import com.horizon.util.JsonUtil;
import com.horizon.zk.CuratorZKClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Administrator
 * @date 2021/9/5
 */
@Data
@Slf4j
public class ImLoadBalance {
    // zk客户端
    private CuratorFramework client = null;
    private String managerPath;

    public ImLoadBalance(CuratorZKClient curatorZKClient) {
        this.client = curatorZKClient.getClient();
        managerPath = ServerConstants.MANAGE_PATH;
    }

    //获取最小的im节点
    public ImNode getBestWorker() {
        List<ImNode> workers = getWorkers();
        workers.stream().forEach(node->{
            log.info("节点信息:{}", JsonUtil.pojoToJson(node));
        });
        ImNode best = balance(workers);
        return best;
    }

    //按照负载排序
    protected ImNode balance(List<ImNode> items) {
        if (items.size() > 0)
        {
            // 根据balance值由小到大排序
            Collections.sort(items);

            // 返回balance值最小的那个
            ImNode node = items.get(0);

            log.info("最佳的节点为：{}", JsonUtil.pojoToJson(node));
            return node;
        } else
        {
            return null;
        }
    }

    public List<ImNode> getWorkers() {
        List<ImNode> worker = new ArrayList<>();

        List<String> children = null;
        try {
            children = client.getChildren().forPath(managerPath);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        for (String child:children) {
            log.info("child:", child);
            byte[] payload = null;
            try {
                payload = client.getData().forPath(managerPath+"/"+child);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (payload== null) {
                continue;
            }
            ImNode node = JsonUtil.jsonBytes2Object(payload, ImNode.class);
            node.setId(this.getIdByPath(child));
            worker.add(node);
        }

        return worker;
    }

    public long getIdByPath(String path) {
        String sid = null;
        if (null == path) {
            throw new RuntimeException("节点路径有误");
        }
        int index = path.lastIndexOf(ServerConstants.PATH_PREFIX_NO_STRIP);
        if (index >= 0) {
            index += ServerConstants.PATH_PREFIX_NO_STRIP.length();
            sid = index <= path.length() ? path.substring(index) : null;
        }

        if (null == sid) {
            throw new RuntimeException("节点ID获取失败");
        }

        return Long.parseLong(sid);

    }

    public void removeWorkers() {
        try {
            client.delete().deletingChildrenIfNeeded().forPath(managerPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
